package com.fanyue.modules.wzb.service.impl;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.fanyue.core.base.BaseServiceImpl;
import com.fanyue.core.cache.CoolCache;
import com.fanyue.core.exception.CoolPreconditions;
import com.fanyue.core.request.R;
import com.fanyue.core.util.CoolSecurityUtil;
import com.fanyue.core.util.DatabaseDialectUtils;
import com.fanyue.modules.base.entity.sys.BaseSysUserEntity;
import com.fanyue.modules.base.service.sys.BaseSysPermsService;
import com.fanyue.modules.base.service.sys.BaseSysUserService;
import com.fanyue.modules.wzb.entity.AppUserEntity;
import com.fanyue.modules.wzb.entity.CargoEntity;
import com.fanyue.modules.wzb.entity.ClothingInfoEntity;
import com.fanyue.modules.wzb.entity.ClothingRecordEntity;
import com.fanyue.modules.wzb.mapper.CargoMapper;
import com.fanyue.modules.wzb.service.CargoService;
import com.fanyue.modules.wzb.service.ClothingInfoService;
import com.fanyue.modules.wzb.service.ClothingRecordService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.tangzc.autotable.core.constants.DatabaseDialect;
import io.netty.util.internal.StringUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.fanyue.modules.base.entity.sys.table.BaseSysDepartmentEntityTableDef.BASE_SYS_DEPARTMENT_ENTITY;
import static com.fanyue.modules.wzb.entity.table.AppUserEntityTableDef.APP_USER_ENTITY;
import static com.fanyue.modules.wzb.entity.table.AppUserFaceRecordEntityTableDef.APP_USER_FACE_RECORD_ENTITY;
import static com.fanyue.modules.wzb.entity.table.CargoEntityTableDef.CARGO_ENTITY;
import static com.fanyue.modules.wzb.entity.table.ClothingInfoEntityTableDef.CLOTHING_INFO_ENTITY;


/**
 * 系统用户
 */
@Service
@RequiredArgsConstructor
public class CargoServiceImpl extends BaseServiceImpl<CargoMapper, CargoEntity> implements CargoService {

    final private CoolCache coolCache;
    final private BaseSysUserService baseSysUserService;
    final private ClothingInfoService clothingInfoService;
    final private ClothingRecordService clothingRecordService;

    @Override
    public Object page(JSONObject requestParams, Page<CargoEntity> page, QueryWrapper qw) {
        String keyWord = requestParams.getStr("keyWord");
        Integer category = requestParams.getInt("category");
        Integer isPrivate = requestParams.getInt("isPrivate");
        Integer season = requestParams.getInt("season");
        Integer status = requestParams.getInt("status");
        Long[] departmentIds = requestParams.get("departmentIds", Long[].class);
        JSONObject tokenInfo = CoolSecurityUtil.getAdminUserInfo(requestParams);
        // 用户的部门权限
        Long[] permsDepartmentArr = coolCache.get("admin:department:" + tokenInfo.get("userId"),
                Long[].class);
        String databaseDialect = DatabaseDialectUtils.getDatabaseDialect();
        if (databaseDialect.equals(DatabaseDialect.PostgreSQL)) {
            // 兼容postgresql
        } else {
            qw.select(CARGO_ENTITY.ALL_COLUMNS,
                    CLOTHING_INFO_ENTITY.CODE.as("clothingCode"),
                    BASE_SYS_DEPARTMENT_ENTITY.NAME.as("departmentName"));
        }
        qw.from(CARGO_ENTITY)
                .leftJoin(CLOTHING_INFO_ENTITY)
                .on(CARGO_ENTITY.CLOTHING_ID.eq(CLOTHING_INFO_ENTITY.ID))
                .leftJoin(BASE_SYS_DEPARTMENT_ENTITY)
                .on(CARGO_ENTITY.DEPARTMENT_ID.eq(BASE_SYS_DEPARTMENT_ENTITY.ID));

        if (StrUtil.isNotEmpty(keyWord)) {
            qw.and(CARGO_ENTITY.POSITION.like(keyWord));
        }
        qw.and(CARGO_ENTITY.STATUS.eq(status, status != null));
        qw.and(CARGO_ENTITY.CATEGORY.eq(category, category != null));
        qw.and(CARGO_ENTITY.IS_PRIVATE.eq(isPrivate, isPrivate != null));
        qw.and(CARGO_ENTITY.SEASON.eq(season, season != null));

        // 筛选部门
        qw.and(CARGO_ENTITY.DEPARTMENT_ID.in(departmentIds,
                ArrayUtil.isNotEmpty(departmentIds)));
        // 过滤部门权限
        qw.and(CARGO_ENTITY.DEPARTMENT_ID.in(
                permsDepartmentArr == null || permsDepartmentArr.length == 0 ? new Long[]{null}
                        : permsDepartmentArr,
                !CoolSecurityUtil.getAdminUsername().equals("admin")));
        if (databaseDialect.equals(DatabaseDialect.PostgreSQL)) {
            // 兼容postgresql
            qw.groupBy("base_sys_department.name");
        } else {
            qw.groupBy(CARGO_ENTITY.ID);
        }
        qw.orderBy(CARGO_ENTITY.CREATE_TIME.desc());
        qw.orderBy(CARGO_ENTITY.POSITION.asc());
        return mapper.paginate(page, qw);
    }

    @Override
    public Long add(JSONObject requestParams, CargoEntity entity) {
        JSONObject tokenInfo = requestParams.getJSONObject("tokenInfo");
        BaseSysUserEntity sysUserEntity = baseSysUserService.getById(tokenInfo.get("userId").toString());
        CargoEntity check = getOne(
                QueryWrapper.create().eq(CargoEntity::getPosition, entity.getPosition()));
        CoolPreconditions.check(check != null, "位置已存在");
        if (entity.getCode() != null && entity.getCode().equals("")) {
            CargoEntity check2 = getOne(
                    QueryWrapper.create().eq(CargoEntity::getCode, entity.getCode()));
            CoolPreconditions.check(check2 != null, "编号已存在");
        }
        if (entity.getCategory() == 3 || entity.getCategory() == 4) {
            entity.setSeason(0);
        }
        super.add(requestParams, entity);

        //判断是否为专属货位
        if (entity.getIsPrivate() == 1) {
            ClothingInfoEntity clothingInfo = clothingInfoService.getById(entity.getClothingId());
            //判断当前被服状态，如果是在库状态，则进行调货，其他不管
            if (clothingInfo.getStatus() == 1 && !entity.getId().equals(clothingInfo.getCargoId())) {
                CargoEntity oldCargo = mapper.selectOneById(clothingInfo.getCargoId());
                ClothingRecordEntity clothingRecord1 = new ClothingRecordEntity();
                clothingRecord1.setCreateTime(new Date());
                clothingRecord1.setClothingId(clothingInfo.getId());
                clothingRecord1.setClothingCode(clothingInfo.getCode());
                clothingRecord1.setCargoId(oldCargo.getId());
                clothingRecord1.setCargoPosition(oldCargo.getPosition());
                clothingRecord1.setSysUserId(sysUserEntity.getId());
                clothingRecord1.setSysUserName(sysUserEntity.getName());
                clothingRecord1.setDepartmentId(clothingInfo.getDepartmentId());
                clothingRecord1.setType(3);
                clothingRecord1.setStatus(1);
                ClothingRecordEntity clothingRecord2 = new ClothingRecordEntity();
                clothingRecord2.setCreateTime(new Date());
                clothingRecord2.setClothingId(clothingInfo.getId());
                clothingRecord2.setClothingCode(clothingInfo.getCode());
                clothingRecord2.setCargoId(entity.getId());
                clothingRecord2.setCargoPosition(entity.getPosition());
                clothingRecord2.setSysUserId(sysUserEntity.getId());
                clothingRecord2.setSysUserName(sysUserEntity.getName());
                clothingRecord2.setDepartmentId(clothingInfo.getDepartmentId());
                clothingRecord2.setType(4);
                clothingRecord2.setStatus(1);
                clothingRecordService.save(clothingRecord2);
                clothingRecordService.save(clothingRecord1);
                //将之前的货位腾空
                oldCargo.setStatus(0);
                //取消专属
                oldCargo.setIsPrivate(0);
                oldCargo.setClothingId(0L);
                mapper.update(oldCargo);
                entity.setStatus(1);
                mapper.update(entity);
            }
            clothingInfo.setCargoId(entity.getId());
            clothingInfoService.update(clothingInfo);
        }
        return entity.getId();
    }

    @Override
    public boolean update(JSONObject requestParams, CargoEntity entity) {
        JSONObject tokenInfo = requestParams.getJSONObject("tokenInfo");
        BaseSysUserEntity sysUserEntity = baseSysUserService.getById(tokenInfo.get("userId").toString());
        CargoEntity check = getOne(
                QueryWrapper.create().eq(CargoEntity::getPosition, entity.getPosition())
                        .ne(CargoEntity::getId, entity.getId()));
        CoolPreconditions.check(check != null, "位置已存在");
        if (entity.getCode() != null && entity.getCode().equals("")) {
            CargoEntity check2 = getOne(
                    QueryWrapper.create().eq(CargoEntity::getCode, entity.getCode())
                            .ne(CargoEntity::getId, entity.getId()));
            CoolPreconditions.check(check2 != null, "编号已存在");
        }
        if (entity.getCategory() == 3 || entity.getCategory() == 4) {
            entity.setSeason(0);
        }
        //判断当前货位是否有东西，有则需要进行下架物品后才能操作专属货位
        CargoEntity cargo = getById(entity.getId());
        //判断是否为专属货位
        if (entity.getIsPrivate() == 1) {
            CoolPreconditions.check(cargo.getStatus() == 1, "当前货位已存入物品，需要进行下架物品后才能操作专属货位");
            ClothingInfoEntity clothingInfo = clothingInfoService.getById(entity.getClothingId());
            //判断当前被服状态，如果是在库状态，则进行调货，其他不管
            if (clothingInfo.getStatus() == 1 && !entity.getId().equals(clothingInfo.getCargoId())) {
                CargoEntity oldCargo = mapper.selectOneById(clothingInfo.getCargoId());
                ClothingRecordEntity clothingRecord1 = new ClothingRecordEntity();
                clothingRecord1.setCreateTime(new Date());
                clothingRecord1.setClothingId(clothingInfo.getId());
                clothingRecord1.setClothingCode(clothingInfo.getCode());
                clothingRecord1.setCargoId(oldCargo.getId());
                clothingRecord1.setCargoPosition(oldCargo.getPosition());
                clothingRecord1.setSysUserId(sysUserEntity.getId());
                clothingRecord1.setSysUserName(sysUserEntity.getName());
                clothingRecord1.setDepartmentId(clothingInfo.getDepartmentId());
                clothingRecord1.setType(3);
                clothingRecord1.setStatus(1);
                ClothingRecordEntity clothingRecord2 = new ClothingRecordEntity();
                clothingRecord2.setCreateTime(new Date());
                clothingRecord2.setClothingId(clothingInfo.getId());
                clothingRecord2.setClothingCode(clothingInfo.getCode());
                clothingRecord2.setCargoId(entity.getId());
                clothingRecord2.setCargoPosition(entity.getPosition());
                clothingRecord2.setSysUserId(sysUserEntity.getId());
                clothingRecord2.setSysUserName(sysUserEntity.getName());
                clothingRecord2.setDepartmentId(clothingInfo.getDepartmentId());
                clothingRecord2.setType(4);
                clothingRecord2.setStatus(1);
                clothingRecordService.save(clothingRecord2);
                clothingRecordService.save(clothingRecord1);
                //将之前的货位腾空
                oldCargo.setStatus(0);
                //取消专属
                oldCargo.setIsPrivate(0);
                oldCargo.setClothingId(0L);
                mapper.update(oldCargo);
                entity.setStatus(1);
            }
            clothingInfo.setCargoId(entity.getId());
            clothingInfoService.update(clothingInfo);
        }
        return super.update(requestParams, entity);
    }

    @Override
    public Object list(JSONObject requestParams, QueryWrapper queryWrapper) {
        Long clothingId = requestParams.getLong("clothingId");
        Integer status = requestParams.getInt("status");
        Integer season = requestParams.getInt("season");
        Integer category = requestParams.getInt("category");
        Long departmentId = requestParams.getLong("departmentId");
        queryWrapper.from(CARGO_ENTITY);
        if (status != null) {
            queryWrapper.and(CARGO_ENTITY.STATUS.eq(status));
        }
        if (category != null) {
            queryWrapper.and(CARGO_ENTITY.CATEGORY.eq(category));
        }
        if (season != null) {
            queryWrapper.and(CARGO_ENTITY.SEASON.eq(season));
        }
        if (departmentId != null) {
            queryWrapper.and(CARGO_ENTITY.DEPARTMENT_ID.eq(departmentId));
        }
        List<CargoEntity> list = mapper.selectListByQuery(queryWrapper);
        if (clothingId != null) {
            ClothingInfoEntity clothing = clothingInfoService.getById(clothingId);
            if (clothing.getStatus() == 1) {
                CargoEntity cargo = mapper.selectOneById(clothing.getCargoId());
                if (ObjectUtil.isNotEmpty(cargo)) {
                    list.add(cargo);
                }
            }
        }
        return list;
    }

    @Override
    public List<CargoEntity> listByInfo(CargoEntity cargo) {
        QueryWrapper queryWrapper = new QueryWrapper();
        // 用户的部门权限
        Long[] permsDepartmentArr = cargo.getDepartmentIds();
        queryWrapper.select(CARGO_ENTITY.ALL_COLUMNS);
        queryWrapper.from(CARGO_ENTITY);
        if (permsDepartmentArr != null && permsDepartmentArr.length > 0) {
            queryWrapper.and(CARGO_ENTITY.DEPARTMENT_ID.in(
                    permsDepartmentArr,
                    !CoolSecurityUtil.getAdminUsername().equals("admin")));
            queryWrapper.groupBy(CARGO_ENTITY.ID);
        }
        queryWrapper.and(CARGO_ENTITY.STATUS.eq(cargo.getStatus(), cargo.getStatus() != null));
        queryWrapper.and(CARGO_ENTITY.DEPARTMENT_ID.eq(cargo.getDepartmentId(), cargo.getDepartmentId() != null));
        queryWrapper.and(CARGO_ENTITY.IS_PRIVATE.eq(cargo.getIsPrivate(), cargo.getIsPrivate() != null));
        queryWrapper.and(CARGO_ENTITY.FACE_RECORD_ID.eq(cargo.getFaceRecordId(), cargo.getFaceRecordId() != null));
        //queryWrapper.and(CARGO_ENTITY.TYPE.eq(cargo.getType(), StrUtil.isNotEmpty(cargo.getType())));
        queryWrapper.and(CARGO_ENTITY.CLOTHING_ID.eq(cargo.getClothingId(), cargo.getClothingId() != null));
        queryWrapper.and(CARGO_ENTITY.CATEGORY.eq(cargo.getCategory(), cargo.getCategory() != null));
        queryWrapper.and(CARGO_ENTITY.SEASON.eq(cargo.getSeason(), cargo.getSeason() != null));

        return mapper.selectListByQuery(queryWrapper);
    }

    @Override
    public R addByBatch(JSONObject requestParams) {
        String prefix = requestParams.getStr("prefix");
        String suffix = requestParams.getStr("suffix");
        Integer num = requestParams.getInt("num");
        Integer spaceNum = requestParams.getInt("spaceNum");
        Integer startNum = requestParams.getInt("startNum");
        Integer season = requestParams.getInt("season");
        Integer category = requestParams.getInt("category");
        CoolPreconditions.check(StrUtil.isEmpty(prefix) || num == null || spaceNum == null || category == null, "缺少参数");
        CoolPreconditions.check(num < 1, "生成数量错误");
        CoolPreconditions.check(spaceNum < 1, "累加数量错误");

        List<CargoEntity> cargoList = new ArrayList<>();
        if (startNum == null) {
            startNum = 1;
        }
        for (int i = 0; i < num; i++) {
            String position = prefix + startNum;
            /*if (startNum < 10) {
                position = prefix + "00" + startNum;
            } else if (startNum < 100) {
                position = prefix + "0" + startNum;
            } else {
                position = prefix + startNum;
            }*/
            if (StrUtil.isNotEmpty(suffix)) {
                position = position + suffix;
            }
            CargoEntity cargo = new CargoEntity();
            cargo.setPosition(position);
            if (category == 3 || category == 4) {
                cargo.setSeason(0);
            } else {
                cargo.setSeason(season);
            }
            cargo.setCategory(category);
            cargo.setIsPrivate(0);
            cargo.setStatus(0);
            startNum = startNum + spaceNum;
            cargoList.add(cargo);
        }
        saveBatch(cargoList);
        return R.ok();
    }

    @Override
    public boolean delete(JSONObject requestParams, Long... ids) {
        super.delete(ids);
        List<ClothingInfoEntity> clothingUpDateList = new ArrayList<>();
        for (Long id: ids) {
            ClothingInfoEntity selectClothing = new ClothingInfoEntity();
            selectClothing.setStatus(1);
            selectClothing.setCargoId(id);
            List<ClothingInfoEntity> clothingList = clothingInfoService.listByInfo(selectClothing);
            for (ClothingInfoEntity clothing: clothingList) {
                clothing.setStatus(0);
                clothingUpDateList.add(clothing);
            }
        }
        clothingInfoService.updateBatch(clothingUpDateList);
        return true;
    }
}